/**
 * Copyright(c) kyle.
 */
package org.example.AIO;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * AIO服务端
 *
 * @author kyle
 * @version 1.00.00
 * @since [2020-10-19 20:02]
 * @updateUser [Kyle]
 * @updateRemark [说明本次修改内容]
 * @date [2020-10-19 20:02]
 */
public class AIOServer {
    private final int port;//端口

    public AIOServer(final int pPort) {
        this.port = pPort;
        listen();
    }

    public static void main(String[] args) {
        int port = 65432;
        new AIOServer(port);
    }

    private void listen() {
        try {
            @SuppressWarnings("AlibabaThreadPoolCreation")
            ExecutorService lvExecutorService = Executors.newCachedThreadPool();
            AsynchronousChannelGroup threadGroup = AsynchronousChannelGroup.withCachedThreadPool(lvExecutorService, 1);
            final AsynchronousServerSocketChannel server = AsynchronousServerSocketChannel.open(threadGroup);

            server.bind(new InetSocketAddress(port));
            System.out.println("服务已启动，监听端口" + port);
            server.accept(null, new CompletionHandler<AsynchronousSocketChannel, Object>() {
                private final ByteBuffer buffer = ByteBuffer.allocateDirect(1024);

                @Override
                public void completed(final AsynchronousSocketChannel result, final Object attachment) {
                    System.out.println("I/O 操作成功，开始获取数据");
                    try {
                        buffer.clear();//清空
                        result.read(buffer).get();//将数据读出
                        buffer.flip();//转换成写模式
                        result.write(buffer);//将数据写回
                        buffer.flip();//转换成读模式
                    } catch (InterruptedException | ExecutionException pE) {
                        pE.printStackTrace();
                    } finally {
                        try {
                            result.close();
                        } catch (IOException pE) {
                            pE.printStackTrace();
                        }
                        server.accept(null, this);
                    }
                }

                @Override
                public void failed(final Throwable exc, final Object attachment) {
                    System.out.println("I/O 操作失败" + exc);
                }
            });

            Thread.sleep(Integer.MAX_VALUE);
        } catch (IOException | InterruptedException pE) {
            pE.printStackTrace();
        }
    }
}
